﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
using System.Reflection;
using YiSha.Util;

namespace YiSha.Entity
{
    /// <summary>
    /// 数据库上下文
    /// </summary>
    public class MyDbContext : DbContext
    {
        /// <summary>
        /// LoggerFactory
        /// </summary>
        private readonly ILoggerFactory _loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());

        /// <summary>
        /// 配置要使用的数据库
        /// </summary>
        /// <param name="optionsBuilder">上下文选项生成器</param>
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //读取配置
            var dbConnect = GlobalContext.SystemConfig.DBConnectionString;
            var dbTimeout = GlobalContext.SystemConfig.DBCommandTimeout;
            //SQLite
            optionsBuilder.UseSqlite(dbConnect, p =>
            {
                p.CommandTimeout(dbTimeout);
            });
            ////SqlServer
            //optionsBuilder.UseSqlServer(dbConnect, p =>
            //{
            //    p.CommandTimeout(dbTimeout);
            //});
            ////MySql
            //optionsBuilder.UseMySql(dbConnect, ServerVersion.AutoDetect(dbConnect), p =>
            //{
            //    p.CommandTimeout(dbTimeout);
            //});
            ////Oracle
            //optionsBuilder.UseOracle(dbConnect, p =>
            //{
            //    p.CommandTimeout(dbTimeout);
            //});
            //输出执行日志
            optionsBuilder.UseLoggerFactory(_loggerFactory);
            //
            base.OnConfiguring(optionsBuilder);
        }

        /// <summary>
        /// 配置通过约定发现的模型
        /// </summary>
        /// <param name="modelBuilder">模型制作者</param>
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //提取所有模型
            var filePath = GlobalConstant.GetRunPath;
            var root = new DirectoryInfo(filePath);
            var files = root.GetFiles("*.dll");
            foreach (var file in files)
            {
                try
                {
                    if (file.FullName.Contains("Microsoft")) continue;
                    if (file.FullName.Contains("System")) continue;
                    var fileName = file.Name.Replace(file.Extension, "");
                    var assemblyName = new AssemblyName(fileName);
                    var entityAssembly = Assembly.Load(assemblyName);
                    var entityAssemblyType = entityAssembly.GetTypes();
                    var typesToRegister = entityAssemblyType
                        .Where(p => p.Namespace != null)//排除没有 命名空间
                        .Where(p => p.GetCustomAttribute<TableAttribute>() != null)//排除没有 Table
                        .Where(p => p.GetCustomAttribute<NotMappedAttribute>() == null);//排除标记 NotMapped
                    foreach (var type in typesToRegister)
                    {
                        var createInstance = Activator.CreateInstance(type);
                        modelBuilder.Model.AddEntityType(type);
                    }
                }
                catch { }
            }
            //初始化数据库
            //
            //用户表初始化
            modelBuilder.Entity<UserEntity>().HasData(UserDBInitializer.GetData);
            //用户所属表初始化
            modelBuilder.Entity<UserBelongEntity>().HasData(UserBelongDBInitializer.GetData);
            //职位表初始化
            modelBuilder.Entity<PositionEntity>().HasData(PositionDBInitializer.GetData);
            //部门表初始化
            modelBuilder.Entity<DepartmentEntity>().HasData(DepartmentDBInitializer.GetData);
            //角色表初始化
            modelBuilder.Entity<RoleEntity>().HasData(RoleDBInitializer.GetData);
            //菜单表初始化
            modelBuilder.Entity<MenuEntity>().HasData(MenuDBInitializer.GetData);
            //菜单权限表初始化
            modelBuilder.Entity<MenuAuthorizeEntity>().HasData(MenuAuthorizeDBInitializer.GetData);
            //Api日志表初始化
            modelBuilder.Entity<LogApiEntity>().HasData(LogApiDBInitializer.GetData);
            //登录日志表初始化
            modelBuilder.Entity<LogLoginEntity>().HasData(LogLoginDBInitializer.GetData);
            //操作日志表初始化
            modelBuilder.Entity<LogOperateEntity>().HasData(LogOperateDBInitializer.GetData);
            //中国省市县表初始化
            modelBuilder.Entity<AreaEntity>().HasData(AreaDBInitializer.GetData);
            //字典类型表初始化
            modelBuilder.Entity<DataDictEntity>().HasData(DataDictDBInitializer.GetData);
            //字典数据表初始化
            modelBuilder.Entity<DataDictDetailEntity>().HasData(DataDictDetailDBInitializer.GetData);
            //定时任务表初始化
            modelBuilder.Entity<AutoJobEntity>().HasData(AutoJobDBInitializer.GetData);
            //定时任务组表初始化
            modelBuilder.Entity<AutoJobLogEntity>().HasData(AutoJobLogDBInitializer.GetData);
            //新闻表初始化
            modelBuilder.Entity<NewsEntity>().HasData(NewsDBInitializer.GetData);
            //
            base.OnModelCreating(modelBuilder);
        }

        /// <summary>
        /// 部门表
        /// </summary>
        public DbSet<DepartmentEntity> DepartmentEntity { get; set; }

        /// <summary>
        /// 新闻表
        /// </summary>
        public DbSet<NewsEntity> NewsEntity { get; set; }

        /// <summary>
        /// 职位表
        /// </summary>
        public DbSet<PositionEntity> PositionEntity { get; set; }

        /// <summary>
        /// 用户所属表
        /// </summary>
        public DbSet<UserBelongEntity> UserBelongEntity { get; set; }

        /// <summary>
        /// 用户表
        /// </summary>
        public DbSet<UserEntity> UserEntity { get; set; }

        /// <summary>
        /// 中国省市县表
        /// </summary>
        public DbSet<AreaEntity> AreaEntity { get; set; }

        /// <summary>
        /// 定时任务表
        /// </summary>
        public DbSet<AutoJobEntity> AutoJobEntity { get; set; }

        /// <summary>
        /// 定时任务组表
        /// </summary>
        public DbSet<AutoJobLogEntity> AutoJobLogEntity { get; set; }

        /// <summary>
        /// 字典数据表
        /// </summary>
        public DbSet<DataDictDetailEntity> DataDictDetailEntity { get; set; }

        /// <summary>
        /// 字典类型表
        /// </summary>
        public DbSet<DataDictEntity> DataDictEntity { get; set; }

        /// <summary>
        /// Api日志表
        /// </summary>
        public DbSet<LogApiEntity> LogApiEntity { get; set; }

        /// <summary>
        /// 登录日志表
        /// </summary>
        public DbSet<LogLoginEntity> LogLoginEntity { get; set; }

        /// <summary>
        /// 操作日志表
        /// </summary>
        public DbSet<LogOperateEntity> LogOperateEntity { get; set; }

        /// <summary>
        /// 菜单权限表
        /// </summary>
        public DbSet<MenuAuthorizeEntity> MenuAuthorizeEntity { get; set; }

        /// <summary>
        /// 菜单表
        /// </summary>
        public DbSet<MenuEntity> MenuEntity { get; set; }

        /// <summary>
        /// 角色表
        /// </summary>
        public DbSet<RoleEntity> RoleEntity { get; set; }
    }
}
